asp.net MVC5 - 依赖注入和AuthorizeAttribute [英] asp.net MVC5 - Dependency Injection and AuthorizeAttribute

查看:1535
本文介绍了asp.net MVC5 - 依赖注入和AuthorizeAttribute的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我寻觅了很长一段时间我的问题的解决方案。我有一个需要依赖到具有访问的DbContext服务的自定义AuthorizeAttribute。
可悲的是依赖注入没有在自定义AuthorizeAttribute工作,总是空。

我想出了一个(对我来说)可接受的解决方案。现在我想知道如果我的解决方案导致无法预料的行为?

的Global.asax.cs

  CustomAuthorizeAttribute.AuthorizeServiceFactory =()=> unityContainer.Resolve< AuthorizeService>();

CustomAuthorizeAttribute.cs

  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,继承= TRUE,的AllowMultiple = TRUE)]
    公共类CustomAuthorizeAttribute:AuthorizeAttribute
    {
        公共静态Func键< AuthorizeService> AuthorizeServiceFactory {搞定;组; }        公共特权特权{搞定;组; }        保护覆盖布尔AuthorizeCore(HttpContextBase的HttpContext)
        {
            布尔授权= base.AuthorizeCore(HttpContext的);
            如果(!授权)
            {
                返回false;
            }            返回AuthorizeServiceFactory()AuthorizeCore(HttpContext的,特权)。
        }
    }

AuthorizeService.cs

 公共类AuthorizeService
{
    [依赖]
    公共UserService UserService {private的get;组; }    公共BOOL AuthorizeCore(HttpContextBase HttpContext的,特权的特权)
    {
        ApplicationUser用户= UserService.FindByName(httpContext.User.Identity.Name);
        返回UserService.UserHasPrivilege(​​user.Id,privilege.ToString());
    }
}

这是一个可以接受的解决方案?我会遇到讨厌的问题,将来还是有可能使用依赖注入在一个自定义一种更好的方式AuthorizeAttribute?


解决方案

  

我有一个需要依赖于一个自定义AuthorizeAttribute
  服务是有访问的DbContext。可悲的依赖
  注射没有在自定义工作AuthorizeAttribute,总是
  空。


System.Web.Mvc 命名空间 IControllerFactory 的实施创建实例您的控制器 Web请求。控制器工厂使用 System.Web.Mvc.DependencyResolver 来解决每个控制器的依赖关系。

然而, ActionFilters /属性的中的 System.Web.Mvc.DependencyResolver 来拆分HTML相对=nofollow> MVC管道没有从控制器工厂创建。这就是为什么你的依赖一直是

现在, System.Web.Mvc.DependencyResolver 公共静态这样你就可以自己访问它。

 公共类AuthorizeService:AuthorizeAttribute
    {
        私人UserService UserService
        {
            得到
            {
                返回DependencyResolver.Current.GetService< UserService>();
            }
        }        公共BOOL AuthorizeCore(HttpContextBase HttpContext的,特权的特权)
        {
            ApplicationUser用户= UserService.FindByName(httpContext.User.Identity.Name);
            返回UserService.UserHasPrivilege(​​user.Id,privilege.ToString());
        }
    }

假设你的 UserService 有一个依赖范围的的WebRequest 的,即其寿命的一个每Web请求的绑到的HttpContext Web请求这不会构建一个新的 UserService 如果已解决了$ p $的寿命pviously或者如果这是第一次 UserService 已经解决了指定的Web请求后。

I searched a long time for a solution for my problem. I have a custom AuthorizeAttribute that needs a Dependency to a "Service" that has access to a DbContext. Sadly the Dependency Injection did not work in the custom AuthorizeAttribute and was always null.

I came up with an (for me) acceptable solution. Now I want to know if my solution can cause unforeseen behaviour?

Global.asax.cs

 CustomAuthorizeAttribute.AuthorizeServiceFactory = () => unityContainer.Resolve<AuthorizeService>();

CustomAuthorizeAttribute.cs

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        public static Func<AuthorizeService> AuthorizeServiceFactory { get; set; }

        public Privilege Privilege { get; set; }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            bool authorized = base.AuthorizeCore(httpContext);
            if (!authorized)
            {
                return false;
            }

            return AuthorizeServiceFactory().AuthorizeCore(httpContext, Privilege);
        }
    }

AuthorizeService.cs

public class AuthorizeService
{
    [Dependency]
    public UserService UserService { private get; set; }

    public bool AuthorizeCore(HttpContextBase httpContext, Privilege privilege)
    {
        ApplicationUser user = UserService.FindByName(httpContext.User.Identity.Name);
        return UserService.UserHasPrivilege(user.Id, privilege.ToString());
    }
}

Is this an acceptable solution? Will I run into nasty problems in the future or is there maybe a better way to use Dependency Injection in a custom AuthorizeAttribute?

解决方案

I have a custom AuthorizeAttribute that needs a Dependency to a "Service" that has access to a DbContext. Sadly the Dependency Injection did not work in the custom AuthorizeAttribute and was always null.

An implementation of IControllerFactory in the System.Web.Mvc namespace creates instances your Controllers for web requests. The Controller Factory uses System.Web.Mvc.DependencyResolver to resolve dependencies in each controller.

However, ActionFilters/Attributes in the MVC pipeline are not created from the Controller Factory so dependencies are not resolved using System.Web.Mvc.DependencyResolver. This is why your dependency was always null.

Now, System.Web.Mvc.DependencyResolver is public and static so you can access it yourself.

    public class AuthorizeService : AuthorizeAttribute
    {
        private UserService UserService
        {
            get
            {
                return DependencyResolver.Current.GetService<UserService>();
            }
        }

        public bool AuthorizeCore(HttpContextBase httpContext, Privilege privilege)
        {
            ApplicationUser user = UserService.FindByName(httpContext.User.Identity.Name);
            return UserService.UserHasPrivilege(user.Id, privilege.ToString());
        }
    }

Assuming your UserServicehas a dependency scope of WebRequest, i.e. its lifetime is One Per web request and tied to the lifetime of HttpContext of a web request this will not construct a new UserService if one has been resolved previously or after if this is the first time UserService has been resolved for the given web request.

这篇关于asp.net MVC5 - 依赖注入和AuthorizeAttribute的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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