代码之家  ›  专栏  ›  技术社区  ›  Scott

MVC/Unity-如何将依赖项注入自定义FilterAttributes?

  •  7
  • Scott  · 技术社区  · 17 年前

    我有个习惯 HandleErrorAttribute 延伸的 FilterAttribute

    如何让Unity在向该属性注入依赖项的同时将其注入控制器的依赖项本身?

    3 回复  |  直到 14 年前
        1
  •  2
  •   scott scott    17 年前

    大多数情况下,我使用的是他在博客上指出的本的解决方案。

    问题是统一的行为有点不同。

    不能直接注入对筛选器的依赖项,因为它们分别属于IActionFilter和IExceptionFilter类型。这让我相信它们是只读的,事实并非如此。只是Unity需要知道显式类型才能注入。

    因此,在本文提供的重写方法中,Unity用户需要查询有关类型的过滤器,然后构建它们。

    public UnityActionInvoker(IUnityContainer container, IList<Type> typesToInject)
            {
                _container = container;
                _typesToInject = typesToInject;
            }
    

      var needsInjection = filters.Where(filter => typesToInject.Contains(filter.GetType()));
    

    另一个问题是你不能打电话_容器堆积(filter)在foreach循环中,因为过滤器在该上下文中是只读的。

        2
  •  1
  •   Ben Robbins    17 年前

    你有两个选择

    blog post . 它专门处理NInject,但是Unity支持属性注入,因此您可以修改示例以使用Unity。

    这是连接IoC容器的选项,不建议这样做。

    public class MyFilter 
    { 
      IMyService MyService {get; set;}
    
      MyFilter() : MyFilter(MyUnityContainer.Resolve<IMyService>())
      { }
    
      MyFilter(IMyService service)
      {
        MyService = service;
      }
    }
    
        3
  •  1
  •   Mike Dymond    16 年前

    我也遇到了这个问题,现在有了一个可行的解决方案。它类似于上面描述的解决方案,但是有一些细微的差别,并且添加了完整的统一代码。

    首先,出于上述原因,我将使用属性注入,如上所述,我将使用Unity上的构建方法将属性注入已经创建的过滤器。

    为此,我让所有的控制器都继承自一个新的自定义基类。在这个基类上,我重写CreateActionInvoker方法以设置自己的自定义ActionInvoker。

    Protected Overrides Function CreateActionInvoker() As System.Web.Mvc.IActionInvoker
        Return CustomActionInvoker
    End Function
    

    然后在CustomActionInvoker中重写GetFilters方法。

    Protected Overrides Function GetFilters(ByVal controllerContext As ControllerContext, ByVal actionDescriptor As ActionDescriptor) As FilterInfo
        Dim info = MyBase.GetFilters(controllerContext, actionDescriptor)
    
        For Each MyAuthorizationFilter In info.AuthorizationFilters
            MvcApplication.Container.BuildUp(MyAuthorizationFilter.GetType, MyAuthorizationFilter)
        Next
    
        For Each MyActionFilter In info.ActionFilters
            MvcApplication.Container.BuildUp(MyActionFilter.GetType, MyActionFilter)
        Next
    
        For Each MyResultFilter In info.ResultFilters
            MvcApplication.Container.BuildUp(MyResultFilter.GetType, MyResultFilter)
        Next
    
        For Each MyExceptionFilter In info.ExceptionFilters
            MvcApplication.Container.BuildUp(MyExceptionFilter.GetType, MyExceptionFilter)
        Next
    
        Return info
    End Function
    

    与上面所说的相反,我没有发现在For-Each循环中进行堆积会导致任何问题。我还通过使用building方法的其他重载之一,克服了只通过接口引用对象的原始问题,该方法使用系统类型以及现有的对象。

    完成以上所有操作后,我现在可以直接将依赖项注入到我的过滤器中。

    任何意见和想法都非常感谢。