属性注入属性 [英] Property Injection on attributes

查看:160
本文介绍了属性注入属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将一个依赖关系注入到一个自定义的AuthorizeAttribute中,如下所示:

I am trying to inject a dependancy into a custom AuthorizeAttribute as follows:

public class UserCanAccessArea : AuthorizeAttribute
{
    readonly IPermissionService permissionService;

    public UserCanAccessArea() :
        this(DependencyResolver.Current.GetService<IPermissionService>()) { }

    public UserCanAccessArea(IPermissionService permissionService)
    {
        this.permissionService = permissionService;
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        string AreaID =
            httpContext.Request.RequestContext.RouteData.Values["AreaID"] as string;

        bool isAuthorized = false;

        if (base.AuthorizeCore(httpContext))
            isAuthorized = permissionService.UserCanAccessArea(AreaID, httpContext.User);

        return isAuthorized;
    }
}

这个工作,但似乎是解决单身意义我得到了我的以前的问题中描述的问题

This works but seems to be resolving as a singleton meaning I get the problems described in my pervious question

我想做的是使用属性注入,但是由于我的Attribute本身不能被Unity解决我无法找到一种配置容器来拦截和解析属性的方法。我尝试了以下内容:

What I'd like to do is use property injection but as my Attribute itself is not resolved by Unity I'm unable to find a way to configure the container to intercept and resolve a property. I have tried the following:

public class UserCanAccessArea : AuthorizeAttribute
{
    public IPermissionService permissionService { get; set; }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        string AreaID =
            httpContext.Request.RequestContext.RouteData.Values["AreaID"] as string;

        bool isAuthorized = false;

        if (base.AuthorizeCore(httpContext))
            isAuthorized = permissionService.UserCanAccessArea(AreaID, httpContext.User);

        return isAuthorized;
    }
}

容器:

container.RegisterType<UserCanAccessArea>(new InjectionProperty("permissionService"));

但属性在运行时始终为空。

But the property is always null at runtime.

有没有人实现了这一点,如果是的话,你有一个例子?

Has anyone achieved this and if so do you have an example?

推荐答案

。原因在本文中解释:属性中的依赖注入:不要这样做!。总而言之,文章解释说:

You should prevent doing dependency injection into attributes completely. The reason for this is explained in this article: Dependency Injection in Attributes: don’t do it!. In summary the article explains that:


  • 由于不能拦截属性实例的创建,因此不可能进行构造器注入。 CLR被控制。

  • 使用属性注入是脆弱的,应该被阻止。

  • 依赖注入属性使得无法验证
    容器配置的正确性。

  • 框架像MVC和Web API缓存属性,使得很容易意外创建 captive依赖关系导致错误。

  • Constructor injection is not possible, because creation of an Attribute instance cannot be intercepted; the CLR is in control.
  • The use of property injection is fragile and should be prevented.
  • Dependency injection into attributes makes it impossible to verify the correctness of the container's configuration.
  • Frameworks like MVC and Web API cache attributes, making it very easy to accidentally create captive dependencies causing bugs.

您有两个选择这里:


  1. 通过将资源(属性)从其行为(服务)中分离,使属性为被动,如引用的文章

  2. 将属性转换为谦卑对象,如此处所述回答。这意味着你:
  1. Make the attributes passive, by splitting the data (the attribute) from its behavior (the service) as explained in the referenced article.
  2. Turn your attributes into humble objects as explained in this answer. This means you:

  1. 将属性中的所有逻辑提取到包含所有依赖关系的自定义服务。

  2. 在容器中注册该服务使用属性的方法( AuthorizeCore 在您的情况下)只能从服务定位器/ DependencyResolver解析服务,并调用服务的方法。这里要注意的是,您不能执行构造函数注入,属性注入,并且服务不能存储在属性私有状态(如您已经注意到)。

  1. extract all logic from the attribute into a custom service that contains all dependencies.
  2. Register that service in your container.
  3. let the attribute's method (AuthorizeCore in your case) do nothing more than resolving the service from the service locator / DependencyResolver and call the service's method. Important to note here is that you cannot do constructor injection, property injection and the service cannot be stored in the attributes private state (as you already noticed).


使用哪个选项:


  • 如果您使用选项1非常希望保持您的设计干净,或者您需要应用这种方式的几个属性,或者您想要应用属性在不依赖于System.Web.Mvc的程序集中定义。

  • 否则使用选项2.

这篇关于属性注入属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆