c# - 如何包装和替换 ASP.NET 5 配置中的默认组件之一

标签 c# asp.net .net configuration asp.net-core

ASP.NET 5 (RC1) 为我们提供了一个全新的配置模型,我们可以在其中向 ServiceDescriptor 对象集合添加/替换配置。替换默认实现很简单,例如:

services.Add(ServiceDescriptor.Instance<IHttpContextAccessor>(
    new MyHttpContextAccessor()));

但是,我无法找到一种方法来扩展具有额外行为的现有注册(通过修饰)。换句话说,我想用内部使用内置版本的自定义版本替换内置版本。以这种方式扩展框架行为当然是很常见的。例如:

// How to get the instance here???
IHttpContextAccessor original = 
    services.Last(service => service.ServiceType == typeof(IHttpContextAccessor));

services.Add(ServiceDescriptor.Instance<IHttpContextAccessor>(
    new HttpContextAccessorDecorator(original)));

请注意,IHttpContextAccessor 的使用只是一个示例,但确实有效地说明了问题。 services 集合包含 ServiceDescriptor 对象,对于 IHttpContextAccessorImplementationInstanceImpementationFactory 属性为空,因此无法获取原始实例。我们不能在装饰器中注入(inject) IServiceProvider 来延迟注册,因为一旦我们在装饰器中请求 IHttpContextAccessor ,我们将得到相同的装饰器,这将导致计算器异常。

有趣的是,使用 MVC 5 和 Web API,这实际上真的很简单。

如何使用 ASP.NET 5 实现同样的目标?

最佳答案

可以通过构建“中间”服务提供商以一种hacky的方式实现这一点。然后您可以检索原始实现的实例并在创建您自己的实例时使用它:

var innerSp = services.BuildServiceProvider();
var original = innerSp.GetService<IHttpContextAccessor>();
services.AddInstance<IHttpContextAccessor>(new HttpContextAccessorDecorator(original));

这需要 Microsoft.Extensions.DependencyInjection 包(不是 Abstractions 包),因为它使用内部 ServiceProvider 实现。

当然,这是一个糟糕的解决方案,我同意我们需要更好的解决方案。

关于c# - 如何包装和替换 ASP.NET 5 配置中的默认组件之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34206466/

相关文章:

c# - 如何从 SQL Server 获取 ado.net 中数字数据类型的值

c# - 如何知道谁连接到 Tibco EMS 队列

asp.net - 对于多部分网站,使用嵌套母版页或用户控件更好吗?

asp.net - ASCX 控件 ASP.NET - 找不到可见方法

asp.net - 建立与 SQL Server 的连接时出现与网络相关或特定于实例的错误

c# - 如何同步.NET中的并行 Action ?

类内的 C# 命名空间?

c# - 在 C# winform 中使用 app.config 访问数据库连接字符串

c# - 如何使用 Doubles 检测精度的完全损失?

asp.net - 开发或部署 .NET 应用程序是否需要付费?