我正在使用Asp.Net Core RC1,并且我已经从模型生成器(来自HttpContext
的拦截器)生成的实例访问Castle.Core
实例,精确)。模型生成器必须是整个应用程序的单个实例。
我需要在启动文件中创建ModelGenerator
的实例,因为它用于配置某些序列化程序所需的静态lambda。序列化程序是静态注册的,所以我必须写入启动:
var modelGenerator = new ModelGenerator();
Serializers.Configure(modelGenerator); // static use of model generator instance
我还将modelGenerator添加为用于DI的其他用途的单例实例。
services.AddInstance<IModelGenerator>(modelGenerator);
我对DI所做的是从ModelGenerator的构造函数中获取IHttpContextAccessor
接口,但在此上下文中我不能因为我在启动时没有实例。我需要类似ServiceLocator的东西从ModelGenerator调用,或者我忽略的其他一些模式。
如何从ModelGenerator生成的拦截器中获取更新的HttpContext实例以及当前请求的信息?
答案 0 :(得分:3)
似乎无法在应用程序启动时获取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...
}
第二个问题可以通过将您需要HttpContext
的任何初始化调用移入全局过滤器来解决。
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();
}
}
并全局注册过滤器:
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
才能生效,那么您需要将该调用移至全局过滤器中。