设置可以注入的填充对象的最佳方法是什么?
What is the best way to set a filled object that can be injected?
我用的是.net core api 5.我想实现的是根据查询字符串填充一个对象。然后,当这个对象被填充时,我想将这个对象注入到需要该信息的 classes 中。
我现在的做法是创建一个 class 并将此 class 注册为单例。
接下来,我创建了一些中间件来读取查询字符串、获取已注册的单例并设置它的值:
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,
};
}
}
接下来我可以在任何我想访问它的值的地方注入 ValuesObject
。
虽然这工作正常,但我想知道是否有更好、更巧妙的方法来实现同样的事情。
这不能正常工作,在请求之间共享单例。两个用户同时访问带有 slug 的页面将导致一个看到另一个的值。放在context的items里就行了,这个属于一个request。
然后在您的控制器中,访问 HttpContext.Items
。
注册对象时即可。
CodeCaster 怎么说,不是实现单例而是 Scoped 或 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,
};
});
我用的是.net core api 5.我想实现的是根据查询字符串填充一个对象。然后,当这个对象被填充时,我想将这个对象注入到需要该信息的 classes 中。
我现在的做法是创建一个 class 并将此 class 注册为单例。
接下来,我创建了一些中间件来读取查询字符串、获取已注册的单例并设置它的值:
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,
};
}
}
接下来我可以在任何我想访问它的值的地方注入 ValuesObject
。
虽然这工作正常,但我想知道是否有更好、更巧妙的方法来实现同样的事情。
这不能正常工作,在请求之间共享单例。两个用户同时访问带有 slug 的页面将导致一个看到另一个的值。放在context的items里就行了,这个属于一个request。
然后在您的控制器中,访问 HttpContext.Items
。
注册对象时即可。 CodeCaster 怎么说,不是实现单例而是 Scoped 或 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,
};
});