当我尝试在同一请求中的2个中间件中访问时,由于某种原因,我的作用域服务似乎正在生成同一类的不同实例。
场景:我正在添加范围内的服务:
public interface ISimplyRecorder
{
void AddInfo(string key, string value);
Dictionary<string, string> GetAllInfo();
}
public class SimplyCoreRecorderService : ISimplyRecorder
{
private Dictionary<string,string> data;
public SimplyCoreRecorderService()
{
data = new Dictionary<string, string>();
}
public void AddInfo(string key,string value)
{
data.Add("",value);
}
public Dictionary<string,string> GetAllInfo()
{
return data;
}
}
然后在startup.cs中的以下内容
services.AddScoped<ISimplyRecorder,SimplyRecorderService>();
现在我在示例中间件的构造函数中调用此服务。我能够使用新实例访问服务并向其中添加数据,然后我调用await _next(context)。但是,当我在我的HomeController中调用服务时,MVC跟随上面的中间件,我似乎得到了一个新的服务实例,即使它是相同的请求。
HomeController中:
ISimplyRecorder _simply;
private IHostingEnvironment _env;
public HomeController(IHostingEnvironment env,ISimplyRecorder simply)
{
_simply = simply;
_env = env;
}
public IActionResult Index()
{
_simply.AddInfo("Home:Action","resulted in index action");
return View();
}
完整代码位于:https://github.com/muqeet-khan/SimplyCore,如果有人想要试一试。
答案 0 :(得分:1)
中间件只有在首次涉及时才会被实例化,然后所有以下请求都由该中间件实例处理。不是每个请求的新中间件实例。
您在中间件的构造函数中获取ISimplyRecorder
并将其“缓存”为私有只读变量。这意味着中间件将获取第一个请求的ISimplyRecorder
实例,然后继续为该实例添加所有以下请求的数据,而不是为ISimplyRecorder
实例添加以下请求的HomeController
实例。 1}}。
要解决此问题,您需要从中间件的ISimplyRecorder
方法获取Invoke
实例。
// using Microsoft.Extensions.DependencyInjection;
public async Task Invoke(HttpContext httpContext)
{
ISimplyRecorder recoder = httpContext.RequestServices.GetRequiredService<ISimplyRecorder>();
}
修改强>
Juergen的评论是正确的,我试了一下。你也可以这样写:
public async Task Invoke(HttpContext httpContext, ISimplyRecorder recorder)
{
// recorder is from DI
}