如何解决应用了Authorize属性的MVC控制器的鸡蛋依赖性解析?

时间:2014-02-05 19:39:34

标签: c# asp.net-mvc asp.net-mvc-4 dependency-injection unity-container

我遇到这种情况,即用户未登录的事实阻止了我的控制器的依赖关系的构建。

[Authorize]
class MyController : Controller
{
    public MyController(MyService service)
    {
    }
}

class MyService
{
    public MyService()
    {
        // requires information which only
        // becomes known after the user logs in
    }
}

我的问题是:我可以做些什么来使MVC框架首先查看Authorize属性,然后解析控制器实例?

上述情况对我来说比以下任何一种情况都要好得多:

  • 更改MyService以便能够在用户登录前创建
  • 注入Func
  • 切换到服务地点

理想情况下,我想在MVC框架中翻转一个开关,说“在你解析控制器之前,检查你是否真的要使用它而不是因为缺乏授权而直接抛弃控制器......“

2 个答案:

答案 0 :(得分:4)

  
    

我遇到这种情况,即用户未登录的事实阻止了我的控制器的依赖关系的构建。

  

这是你问题的根源。

  
    

//需要在用户登录后才知道的信息

  

这意味着该服务的构造函数做得太多了。构造函数不应该只存储传入的依赖项。这样你就可以compose object graphs with confidence

对象图的构建通常应该是静态的。这意味着解析的对象图不应该根据运行时条件而改变(有例外,但这是一个很好的经验法则)。无论用户是否被授权都应该无关紧要,服务类仍然应该被编写和注入。这意味着数据的授权和加载将在以后完成;请求实际执行的时刻(直接在组成对象图之后)。

答案 1 :(得分:1)

您的问题是您并不真正了解MVC请求管道的工作原理。

首先要注意的是,属性本质上是为了与控制器基类中的相同事件相匹配而设计的。在Controller中有一个OnAuthorization方法,这个方法在调用属性OnAuthorization方法之前或之后调用。

因此,为了使它在大致相同的时间调用这两个方法,这意味着必须构造Controller类才能这样做。更重要的是,许多其他内容在授权过滤器之前发生,例如模型绑定,因为您的授权过滤器可能需要模型中的信息来做出决定。

我建议你查看这个pipline图表。

https://www.simple-talk.com/dotnet/.net-framework/an-introduction-to-asp.net-mvc-extensibility/