配置中间件选项
Configuring options for middleware
查看不同的库甚至 Microsoft 代码,我注意到在代码中配置选项的两种不同方式:
在ConfigureServices
注册的时候就可以做到DependencyInjection
:
services.AddMvc(options => { });
或 Configure
app.UseStaticFiles(
new StaticFileOptions
{
ServeUnknownFileTypes = true
});
我试图找出哪种方式用于哪种目的但仍然不知道,假设创建自己的中间件并注册 DI 和用法。
您发现了一个有趣的问题。
查看源代码我发现了以下内容:
所有的中间件注册都是这个UseMiddleware函数的重载,是IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware);
.
的重载
在这些重载中,您可以为中间件硬指定您自己的参数。假设你在构造函数中有几个字符串,DI 容器将无法解决这个问题。
如果未设置参数,它会回退到 IServiceProvider
来解析特定类型。查看扩展名 class:Microsoft.Extensions.Internal.ActivatorUtilities
(内部:Microsoft.AspNetCore.Http.Abstractions.dll
)
提示
至于最佳实践,请考虑以下内容(尽管是我的意见):
- 尽量避免在构造函数中使用简单类型,而是使用选项 class。
- 对于 IOptions,请使用
services.Configure<>()
,因为您可以在此处指定来自 ConfigSection => appsettings 的选项。
- 至于服务:请注意中间件是单例!所以添加一个临时服务,只会为这个中间件解析一次!
我认为最佳做法是:在启动时在 IOC 中将中间件及其依赖项注册为单例。然后自己解决,用方法App.Use([yourDelegate])
.
自己添加
这种方法的优点是它比使用隐藏的微软代码更容易理解+微软最近发布了对 DI 容器的升级来检查你的注册范围是否正确匹配(如果不匹配则警告你)。
这个工具基本上是这样做的:它检查服务的依赖项是否具有比服务本身更小的范围:假设服务是范围:Singleton
并且依赖项是范围Transient
。这意味着如果 Singleton
被解析,Transient
也被解析为这个单例,因此在下次使用这个单例时不会再次解析。 (所以它是一个隐藏的单例用法)。
查看不同的库甚至 Microsoft 代码,我注意到在代码中配置选项的两种不同方式:
在ConfigureServices
注册的时候就可以做到DependencyInjection
:
services.AddMvc(options => { });
或 Configure
app.UseStaticFiles(
new StaticFileOptions
{
ServeUnknownFileTypes = true
});
我试图找出哪种方式用于哪种目的但仍然不知道,假设创建自己的中间件并注册 DI 和用法。
您发现了一个有趣的问题。
查看源代码我发现了以下内容:
所有的中间件注册都是这个UseMiddleware函数的重载,是IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware);
.
在这些重载中,您可以为中间件硬指定您自己的参数。假设你在构造函数中有几个字符串,DI 容器将无法解决这个问题。
如果未设置参数,它会回退到 IServiceProvider
来解析特定类型。查看扩展名 class:Microsoft.Extensions.Internal.ActivatorUtilities
(内部:Microsoft.AspNetCore.Http.Abstractions.dll
)
提示
至于最佳实践,请考虑以下内容(尽管是我的意见):
- 尽量避免在构造函数中使用简单类型,而是使用选项 class。
- 对于 IOptions,请使用
services.Configure<>()
,因为您可以在此处指定来自 ConfigSection => appsettings 的选项。 - 至于服务:请注意中间件是单例!所以添加一个临时服务,只会为这个中间件解析一次!
我认为最佳做法是:在启动时在 IOC 中将中间件及其依赖项注册为单例。然后自己解决,用方法App.Use([yourDelegate])
.
这种方法的优点是它比使用隐藏的微软代码更容易理解+微软最近发布了对 DI 容器的升级来检查你的注册范围是否正确匹配(如果不匹配则警告你)。
这个工具基本上是这样做的:它检查服务的依赖项是否具有比服务本身更小的范围:假设服务是范围:Singleton
并且依赖项是范围Transient
。这意味着如果 Singleton
被解析,Transient
也被解析为这个单例,因此在下次使用这个单例时不会再次解析。 (所以它是一个隐藏的单例用法)。