中间件和Scoped / Singleton对象

时间:2017-06-01 18:27:30

标签: c# dependency-injection asp.net-core-mvc middleware

任何人都可以解释我在这里缺少的东西吗?我使用默认的asp.net核心1.1 MVC模板创建了一个简单的应用程序。我正在使用默认的DI容器,除了添加中间件类和DI配置之外没有做任何其他更改。

问题是当使用对象的Scoped或Singleton实例时,两个地方都没有注入相同的对象。

以下是代码:

public class MyMiddleware
{
    private readonly RequestDelegate _next;

    public MyMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext httpContext, MyInstance myInstance)
    {
        httpContext.Items["myInstance"] = myInstance;
        myInstance.MyProperty = 99;

        await _next(httpContext);
    }
}

public class MyInstance
{
    public int MyProperty { get; set; }
}

在ConfigureServices中我有:

services.AddSingleton<MyInstance>();

在配置中我有:

app.UseMiddleware<MyMiddleware>();

在家庭控制器索引方法中,我有:

public IActionResult Index(MyInstance myInstance)
{
    if (ReferenceEquals(HttpContext.Items["myInstance"], myInstance))
        Debug.WriteLine("Equal!");
    else
        Debug.WriteLine("Not Equal!");

    return View();
}

无论我是使用Scoped还是Singleton生命周期,它总是打印“Not Equal!”。另外,通过调试,我已经验证了HomeController索引中MyProperty上的MyInstance为0。

显然,我在这里遗漏了一些东西。它在.NET Core 2.0 Preview1中也做同样的事情。

这里有什么建议吗?

编辑:

作为另一个测试,我在HomeControll / Index中将MyProperty设置为不同的值,在第二次刷新时,值再次返回到0,所以显然每次都会创建一个新的瞬态实例。 / p>

1 个答案:

答案 0 :(得分:0)

好的,是的。我错过了什么。洛尔。

我会把这作为一个警示故事,因为我学到了一些东西。

首先,我愚蠢地只将实例提供给UseSingletion,我应该将接口映射到实例。但是,这不一定是问题的一部分。我应该做的事情。

其次,我将IMyInstance传递给Index方法,该方法被视为模型绑定对象,而不是注入。我需要注入一个构造函数,我应该注意到,但是没有。

一旦我解决了这些问题,一切都正常。

哦,我学到的是MVC没有注入动作方法,但它确实注入了其他类型的方法(如Middleware Invoke)。

我认为令人惊讶的部分是模型绑定器实际上在没有任何绑定的情况下实现了MyInstance。我似乎记得MVC模型绑定器只有在FormsCollection中至少存在一个属性时才会实例化一个对象。

如果我实际使用了接口映射方法,问题就会变得很明显,因为它会产生关于接口的模型绑定错误。因此,警示故事。