【问题标题】:How to use Ninject to inject services into an authorization filter?如何使用 Ninject 将服务注入授权过滤器?
【发布时间】:2011-06-15 20:37:30
【问题描述】:

我正在使用 asp.net mvc 3、ninject 2.0 和 ninject mvc 3 插件。

我想知道如何将服务层放入我的过滤器(在这种情况下是授权过滤器?)。

我喜欢做构造函数注入,这是可能的还是我必须注入属性?

谢谢

编辑

我有这个用于属性注入,但我的属性始终为空

  [Inject]
        public IAccountService AccountServiceHelper { get; set; }


        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            // check if context is set
            if (httpContext == null)
            {
                throw new ArgumentNullException("httpContext");
            }

            // check if user is authenticated
            if (httpContext.User.Identity.IsAuthenticated == true)
            {
                // stuff here
                return true;
            }

            return false;
        }



    /// <summary>
    /// Application_Start
    /// </summary>
    protected void Application_Start()
    {

        // Hook our DI stuff when application starts
        IKernel kernel = SetupDependencyInjection();

        RegisterMaps.Register();

        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);

    }


    public IKernel SetupDependencyInjection()
    {
        IKernel kernel = CreateKernel();
        // Tell ASP.NET MVC 3 to use our Ninject DI Container
        DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));

        return kernel;
    }

    protected IKernel CreateKernel()
    {
        var modules = new INinjectModule[]
                          {
                             new NhibernateModule(),
                             new ServiceModule(),
                             new RepoModule()
                          };

        return new StandardKernel(modules);
    }


public class ServiceModule : NinjectModule
{
    public override void Load()
    {
        Bind<IAccountService>().To<AccountService>();
    }

}

编辑

我升级到 ninject 2.2,终于可以正常工作了。

编辑 2

我将尝试为我的授权过滤器执行构造方法,但我不确定如何传递角色。我猜我必须通过ninject来做到这一点?

编辑 3

这是我目前所拥有的

 public class MyAuthorizeAttribute : AuthorizeAttribute 
    {
        private readonly IAccountService accountService;

        public MyAuthorizeAttribute(IAccountService accountService)
        {
            this.accountService = accountService;
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            return base.AuthorizeCore(httpContext);
        }
    }

  this.BindFilter<MyAuthorizeAttribute>(FilterScope.Controller, 0)
                .WhenControllerHas<MyAuthorizeAttribute>();

  [MyAuthorize]
    public class MyController : BaseController
    {
}

它告诉我它想要一个无参数构造函数。所以我一定是错过了什么。

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 ninject ninject-2


    【解决方案1】:

    过滤器的问题在于它们是属性。如果你定义了一个属性的构造函数,它需要一些依赖,你将永远无法将它应用于任何方法:因为你传递给属性的所有值在编译时都必须是已知的。

    所以基本上你有两种可能性:

    1. 使用 Ninject 全局应用过滤器,而不是用它装饰你的控制器/动作:

      public interface IFoo { }
      public class Foo : IFoo { }
      
      public class MyFooFilter : AuthorizeAttribute
      {
          public MyFooFilter(IFoo foo)
          {
      
          }
      }
      

      然后配置内核:

      kernel.Bind<IFoo>().To<Foo>();
      kernel.BindFilter<MyFooFilter>(FilterScope.Action, 0).When(
          (controllerContext, actionDescriptor) => 
              string.Equals(
                  controllerContext.RouteData.GetRequiredString("controller"),
                  "home",
                  StringComparison.OrdinalIgnoreCase
              )
      );
      
    2. 使用属性注入:

      public interface IFoo { }
      public class Foo : IFoo { }
      
      public class MyFooFilter : AuthorizeAttribute
      {
          [Inject]
          public IFoo Foo { get; set; }
      }
      

      然后配置内核:

      kernel.Bind<IFoo>().To<Foo>();
      

      并使用您的自定义过滤器装饰一些控制器/动作:

      [MyFooFilter]
      public ActionResult Index()
      {
          return View();
      }
      

    【讨论】:

    • @Darin Dimitrov - 我想我会尝试属性注入。我遇到了问题。我会更新我的帖子。
    • @chobo2,看看我提供的关于你有两种可能性的例子。
    • @Darin Dimitrov- 我一直在读这个 -> planetgeek.ch/2010/11/13/… 他们似乎再次推荐属性注入,因为它是向后兼容的,我猜将来会被替换。如果我选择选项 1。属性标签在控制器/操作方法上的外观如何。如果我继续使用属性注入我缺少的东西,因为我似乎拥有你拥有的东西,但我的财产为空。我知道绑定有效,因为我在构造函数注入中使用了绑定并且它不为空。
    • @chobo2,在这种情况下,您可以执行以下操作:执行我在全新项目中建议的步骤。让它起作用。确保您了解它的工作原理。一旦您确信复制和更新程序集并在现有项目中调整代码。
    • 请注意,您还可以配置过滤器应在操作上有属性时应用,并使用“WhenActionHas()”使用此过滤器传递参数。但是您必须使用新属性而不是过滤器!请参阅我的博客中的“过滤器的条件绑定”和“过滤器配置”章节。
    【解决方案2】:
    猜你喜欢
    • 1970-01-01
    • 2011-12-01
    • 1970-01-01
    • 2016-07-06
    • 2018-06-23
    • 1970-01-01
    • 2017-11-27
    相关资源
    最近更新 更多