【问题标题】:MVC Hangfire Authorization NinjectMVC Hangfire 授权注入
【发布时间】:2015-09-28 14:55:52
【问题描述】:

我想将我的自定义服务注入 Hangfire AuthorizationFilter 并对其进行处理,但我遇到的问题是我的服务始终为空。

Owin 启动类:

 public class Startup
{

    public void Configuration(IAppBuilder app )
    {
        GlobalConfiguration.Configuration
            .UseSqlServerStorage("SomeContext")
            .UseNinjectActivator(new Bootstrapper().Kernel);

        app.UseHangfireDashboard("/hangfire", new DashboardOptions { AuthorizationFilters = new[] { new RestrictiveAuthorizationFilter() } });
        app.UseHangfireServer();
    }
}

自定义过滤器:

public class RestrictiveAuthorizationFilter : IAuthorizationFilter
{

    [Inject]
    public IUserService _userService { get; set; }

    public bool Authorize(IDictionary<string, object> owinEnvironment)
    {

      //do something with _userService but it is always null

      return true;
    }
}

Ninject 内核:

 private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind(x => { x.From(typeof(BookService).Assembly).SelectAllClasses().EndingWith("Service").BindDefaultInterface(); });
        kernel.Bind<LibraryDBContext>().ToSelf().InRequestScope();
        kernel.Bind<IBackgroundJobClient>().To<BackgroundJobClient>();
    }      

我没有看到我的错误,你能帮我吗?

【问题讨论】:

  • 你需要告诉 ninject 建立这个实例,这通常是用kernel.BindFilter&lt;RestrictiveAuthorizationFilter&gt;(FilterScope.Action, null); 完成的。但是我不知道你必须如何将它应用到 Hangfire 仪表板。
  • 按照@BatteryBackupUnit 所说的注册后,将AuthorizationFilters = new[] { new RestrictiveAuthorizationFilter() } 更改为AuthorizationFilters = new[] { injectedFilter } 并将RestrictiveAuthorizationFilter injectedFilter 作为参数。

标签: asp.net-mvc ninject hangfire


【解决方案1】:

您可以将内核作为参数传递给 RestrictiveAuthorizationFilter 构造函数并请求 IUserService。

public class RestrictiveAuthorizationFilter : IAuthorizationFilter 
{   
    public IUserService _userService { get; set; }

    public RestrictiveAuthorizationFilter(IKernel kernel)
    {
        _userService = kernel.Get<IUserService>()
    }

    public bool Authorize(IDictionary<string, object> owinEnvironment)
    {

      //do something with _userService but it is always null

      return true;
    }
}

【讨论】:

  • 很抱歉投了反对票,但如果您进行编辑,就会有赞成票等着您。这是一个将“服务位置”作为anti-pattern 的示例,而不是将IKernel 作为参数,您应该使用您真正想要的东西-IUserService。 (这都是“构造函数注入”的全部内容,这甚至不是绝对必要的,因为该问题已经使用 [Inject] 属性来表示“属性注入”。)完成这项工作的关键部分在我和 @ 的 cmets 中BatteryBackupUnit
  • 过滤器属性实例在每个操作中被无限期地缓存,有效地使它们成为单例。这使得它们不适合 DI,因为属性的依赖项也会被意外提升为单例,这可能会导致各种并发问题。由于此处不能选择 DI,因此建议使用其他机制。这里基本上有两种选择。哪一个最好取决于您的应用程序需要的过滤器属性的数量。如果属性数量有限(少数),最简单的解决方案是在属性中恢复为服务定位器模式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 2020-03-23
  • 1970-01-01
  • 2017-01-14
相关资源
最近更新 更多