无法在aspnetcore 1 - RC1中获得Scoped服务

时间:2016-02-19 05:12:17

标签: asp.net-core asp.net-core-mvc

当我尝试在同一请求中的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,如果有人想要试一试。

1 个答案:

答案 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
}