【问题标题】:Intermediate Service Provider Drawbacks中间服务提供商的缺点
【发布时间】:2020-08-11 15:27:54
【问题描述】:

我正在尝试在 ConfigureServices 方法期间访问自定义类的实例。

我有read,我可以建立一个中间服务提供者来做到这一点:

public void ConfigureServices(IServiceCollection services)
{
    // .... Other Stuff ....
    services.AddSingleton<Wso2Actions>();
    var serviceProvider = services.BuildServiceProvider();
    var wso2Actions = serviceProvider.GetService<Wso2Actions>();
    // .... Other stuff ....

我对这项技术有 3 个问题:

  1. 做这个“中间服务商”有什么缺点?
  2. 我的wso2Actions 对象是否仍由依赖注入框架管理? (好像是后来注入的?)
  3. 我自己“更新”对象会更好吗?
    • var wso2Actions = new Wso2Actions(); services.AddSingleton<Wso2Actions>(wso2Actions);
    • 我似乎记得读过将实例传递到 DI 引擎会导致更差的生命周期管理。

【问题讨论】:

标签: c# asp.net-core dependency-injection asp.net-core-3.1


【解决方案1】:

做这个“中间服务商”有什么弊端?

您最终可能会在您的应用程序中拥有多个容器。这里的主要缺点之一是您的单例服务可以存在于多个容器中。即单个服务的多个实例。

从 ASP.NET Core 3.0 开始,如果您在配置方法中调用 BuildServiceProvider,您会看到警告:

Calling 'BuildServiceProvider' from application code results in an additional copy of
singleton services being created. Consider alternatives such as dependency injecting 
services as parameters to 'Configure'.

Comment from @devNull 提供更多详细信息,如果您也想阅读。

我的 wso2Actions 对象是否仍由依赖注入框架管理?

是的。

(好像是后来注入的?)

没有。例如,如果稍后将wso2Actions 注入到控制器中,则用于解析实例的容器就是 ASP.NET Core 使用的容器。而在您的ConfigureServices 中,实例是使用您的代码构建的瞬态容器解析的。

请注意,这两个容器是独立的,可能包含不同的服务注册。

我自己“更新”对象会更好吗?

如果你愿意使用new,那何乐而不为。

如果你愿意使用依赖注入,根据wso2Actions 的用途,有多种选择:

将您的代码移至Configure

显然你可以将你的代码移动到Configure,它会在容器构建后被调用:

var wso2Actions = app.ApplicationServices.GetService<Wso2Actions>();

使用选项模式

阅读this

services.AddOptions<MyOptions>("optionalName")
    .Configure<Service1, Service2, Service3, Service4, Service5>(
        (o, s, s2, s3, s4, s5) => 
            o.Property = DoSomethingWith(s, s2, s3, s4, s5));

【讨论】:

  • 好答案!但是我需要调用 Wso2Actions 来获取 TokenValidationParametersservices.AddAuthentication().AddJwtBeaerer lambda。 (但我需要在启动时拨打电话,这样我就不必在第一次调用我的服务时等待调用,也就是调用 AddJwtBearer 的 lambda 时。)我不能把它移到Configure 方法。 Aso,我不知道 AddOptions 如何在启动时帮助完成这项工作并将其交给 lambda... 我想我会选择 new Wso2Actions 选项。只需要弄清楚这将如何影响 DI(对象的使用和实例)。
  • 您可以实现IConfigureNamedOptions&lt;JwtBearerOptions&gt;并使用services.ConfigureOptions注册它。然后你可以将Wso2Actions 注入到配置类型中。但是,在实例化 JWT 身份验证处理程序时会调用配置类型,这可能在第一次调用时需要 JWT。所以是的,如果你不介意使用new,那么我想没有比new 更好的解决方案了。
猜你喜欢
  • 2014-08-02
  • 1970-01-01
  • 1970-01-01
  • 2016-08-23
  • 1970-01-01
  • 2017-08-02
  • 2020-09-21
  • 2022-01-19
  • 1970-01-01
相关资源
最近更新 更多