Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Asp.Net核心-需要从生成的实例访问HttpContext实例,而无需依赖项注入_C#_Asp.net_Dependency Injection_Asp.net Core_Service Locator - Fatal编程技术网

C# Asp.Net核心-需要从生成的实例访问HttpContext实例,而无需依赖项注入

C# Asp.Net核心-需要从生成的实例访问HttpContext实例,而无需依赖项注入,c#,asp.net,dependency-injection,asp.net-core,service-locator,C#,Asp.net,Dependency Injection,Asp.net Core,Service Locator,我使用的是Asp.Net Core RC1,我必须从模型生成器生成的实例(确切地说是从Castle.Core的拦截器)访问HttpContext实例。模型生成器必须是贯穿整个应用程序的单个实例 我需要在启动文件中创建一个ModelGenerator的实例,因为它用于配置一些序列化程序所需的静态lambda。序列化程序是静态注册的,因此我必须写入startup: var modelGenerator = new ModelGenerator(); Serializers.Configure(mod

我使用的是Asp.Net Core RC1,我必须从模型生成器生成的实例(确切地说是从
Castle.Core
的拦截器)访问
HttpContext
实例。模型生成器必须是贯穿整个应用程序的单个实例


我需要在启动文件中创建一个
ModelGenerator
的实例,因为它用于配置一些序列化程序所需的静态lambda。序列化程序是静态注册的,因此我必须写入startup:

var modelGenerator = new ModelGenerator();
Serializers.Configure(modelGenerator); // static use of model generator instance
我还将modelGenerator添加为singleton实例,用于DI的其他用途

services.AddInstance<IModelGenerator>(modelGenerator);
services.AddInstance(modelGenerator);
我对DI所做的是从ModelGenerator的构造函数中获取
IHttpContextAccessor
接口,但是在这个上下文中我不能,因为我在启动时没有实例。我需要像ServiceLocator这样的东西从ModelGenerator调用,或者其他一些我忽略的模式


如何从ModelGenerator生成的拦截器中获取更新后的HttpContext实例以及当前请求的信息?

似乎无法在应用程序启动时获取HttpContext的实例。这很有意义-在以前的MVC版本中,这在IIS集成模式或OWIN中是不可能的

因此,您有两个问题:

  • 如何将
    IHttpContextAccessor
    放入序列化程序
  • 如何确保在可用之前不访问
    HttpContext
第一个问题相当简单。您只需要在
IHttpContextAccessor
上使用构造函数注入

public interface ISerializer
{
    void Test();
}

public class ModelGenerator : ISerializer
{
    private readonly IHttpContextAccessor httpContextAccessor;

    public ModelGenerator(IHttpContextAccessor httpContextAccessor)
    {
        this.httpContextAccessor = httpContextAccessor;
    }

    public void Test()
    {
        var context = this.httpContextAccessor.HttpContext;

        // Use the context
    }
}
并注册

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    // Other code...

    // Add the model generator
    services.AddTransient<ISerializer, ModelGenerator>();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    var serializers = app.ApplicationServices.GetServices<ISerializer>();
    foreach (var serializer in serializers)
    {
        Serializers.Configure(serializer);
    }

    // Other code...
}
以及全局注册过滤器:

public void ConfigureServices(IServiceCollection services)
{
    // Other code...

    // Add the global filter for the serializer
    services.AddMvc(options =>
    {
        options.Filters.Add(new SerializerFilter());
    });

    // Other code...
}

如果您的
Serializers.Configure()
方法需要
HttpContext
才能工作,则需要将该调用移动到全局筛选器中。

“序列化程序是静态注册的”-为什么?DI中生命周期管理的全部要点是远离静态实例。如果你不使用静态实例,而是使用单例生活方式,你就不会有这个问题。我知道,但这不是因为我的代码,我无法更改它。
public class SerializerFilter : IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext context)
    {
        // TODO: Put some kind of if condition (possibly a 
        // global static variable) here to ensure this 
        // only runs when needed.
        Serializers.Test();
    }
}