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

Posted

技术标签:

【中文标题】设置可以注入的填充对象的最佳方法是啥?【英文标题】: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

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

【问题讨论】:

【参考方案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 的回答。

以上是关于设置可以注入的填充对象的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用 NSPersistentCloudKitContainer 时预填充核心数据存储的最佳方法是啥?

在 QT 中实现具有多个小部件的视图的最佳方法是啥?

创建和填充数字表的最佳方法是啥?

在 Rails 中播种数据库的最佳方法是啥?

MPNowPlayingInfoCenter:从 URL 设置 MPMediaItemArtwork 的最佳方法是啥?

SQL 注入后清理的最佳方法是啥?