ASP.NET MVC 5 过滤器和注入

Posted

技术标签:

【中文标题】ASP.NET MVC 5 过滤器和注入【英文标题】:ASP.NET MVC 5 Filter and Ninject 【发布时间】:2015-07-15 14:17:32 【问题描述】:

我有这个 DDD 应用程序,它在 Presentation 上有 MVC,带有 Ninject。

我有一个横切层绑定所有层的注入,它就像一个魅力。

我做不到的是过滤属性。我有这个过滤器检查一个 cookie,并根据它的值在数据库上执行查询。使用这种架构,我不能让我的过滤器直接访问我的存储库,这对我正在应用的方法是不尊重的。

我有我的 IFooAppService 接口,并且它的方法最终将访问存储库以进行数据请求。我可以成功地将它注入任何 Controller 构造函数中,它会执行我的 _fooAppService.Query(),但是我在我的应用程序中的某些操作上方有这个 XooFilter,我只是无法将我的 _fooAppService 传递给它。这是我的 XooFilter:

public class XooFilter : ActionFilterAttribute

    private readonly IFooAppService _fooAppService;

    public XooFilter(IFooAppService fooAppService)
    
        _fooAppService = fooAppService;
    

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    
        // LOGIC...

        var fooValue = _fooAppService.Query();

        // MORE LOGIC..
    

但是,当我在任何 Action [XooFilter] 上方插入过滤器时,它就不起作用了。它说过滤器没有包含 0 个元素的构造函数。

我只是想不出如何很好地做到这一点并保持 DDD 和 IoC 的特性。我找到了下面的文章,但找不到任何答案:

Injecting dependencies into ASP.NET MVC 3 action filters. What's wrong with this approach?

【问题讨论】:

Don't inject dependency into your attributes。时期!将您的attributes passive 设为@,或将您的属性设为humble object,如here 所述。 那我该怎么办?每次调用这些过滤器时,我都需要访问数据库。编辑:我对 IoC 和 DI 伙伴还很陌生,但我掌握了基础知识。 阅读参考文章和答案后,您将获得足够的信息来就如何解决问题做出明智的决定。 【参考方案1】:

有一个名为 Ninject.Web.Mvc 的 Ninject 扩展包(您可能已经拥有)。这允许您像这样设置过滤器绑定;

public class LoggingModule : NinjectModule

    public override void Load()
    
        this.Bind<ILog>().ToMethod(GetLogger);
        this.BindFilter<LogFilter>(FilterScope.Controller, 0)
            .WithConstructorArgument("logLevel", Level.Info);
    

    private static ILog GetLogger(IContext ctx)
    
        var filterContext = ctx.Request.ParentRequest.Parameters
            .OfType<FilterContextParameter>().SingleOrDefault();

        return
            LogManager.GetLogger(filterContext == null
                ? ctx.Request.Target.Member.DeclaringType
                : filterContext.ActionDescriptor.ControllerDescriptor.ControllerType);
    

注意BindFilter 方法调用。这适用于 v.3.3.0。

一旦配置好,使用它就像通常的构造函数注入一样;

public class LogFilter : IActionFilter

    public LogFilter(ILog logger)
    
        // store your instance of "logger" here
    

【讨论】:

感谢您的回复。今天我只做一个受保护的构造函数。【参考方案2】:

你可以这样解决你的服务

System.Web.Mvc.DependencyResolver.Current.GetService(typeof (IFooAppService ));

【讨论】:

这不是一种资源友好的方法。

以上是关于ASP.NET MVC 5 过滤器和注入的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET MVC 学习之过滤器你怎么看?

Asp.Net MVC学习总结之过滤器详解(转载)

如何使用 mvc 6、asp.net 5 注册全局过滤器

ASP.Net MVC过滤器

Asp.net模块化开发之Mvc分区扩展框架

ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 25. 过滤器