【问题标题】:What is the best way to set a filled object that can be injected?设置可以注入的填充对象的最佳方法是什么?
【发布时间】:2021-12-07 01:29:11
【问题描述】:

我正在使用.net core api 5。我想要实现的是根据查询字符串填充一个对象。然后,当这个对象被填充时,我想把这个对象注入到需要该信息的类中。

我现在的做法是创建一个类,并将这个类注册为单例。

接下来,我创建了一些中间件来读取查询字符串,获取注册的单例并设置它的值:

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

虽然这很好用,但我想知道是否有更好的,也许是更简洁的方法来实现同样的目标。

【问题讨论】:

    标签: c# .net-core asp.net-core-webapi


    【解决方案1】:

    注册对象时即可。 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,
                    };
    
                });
    

    【讨论】:

    • 谢谢。您认为这是一种填充对象的好方法,以便可以将其注入任何地方吗?还是您认为有更好的方法?
    • 我认为这是最好的版本。也因为它易于理解且易于修复。
    • 好的,非常感谢:)
    【解决方案2】:

    这不正常,单例在请求之间共享。两个用户同时访问一个带有 slug 的页面会导致一个看到另一个的值。放在上下文的items里就行了,这属于一个请求。

    然后在你的控制器中,访问HttpContext.Items

    【讨论】:

    • 嗯,你是对的。但主要是这个对象没有在控制器中使用,我在单独的类中使用它。关于如何做到这一点的任何想法?
    • 是的,我错过了,请参阅@Den 的回答。
    猜你喜欢
    • 2015-12-18
    • 2020-10-14
    • 2012-08-30
    • 2021-05-20
    • 1970-01-01
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多