设置可以注入的填充对象的最佳方法是什么?

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,
                };

            });