MVC / Unity - How to embed dependencies in FilterAttributes user attributes?

I have a custom HandleErrorAttribute that extends FilterAttribute .

How can I add Unity dependencies to this attribute at the same time that it introduces the controller dependencies themselves?

+7
asp.net-mvc unity-container
source share
3 answers

Ok, got it.

I basically used Ben's solution above from the blog post he pointed to.

The problem is that Unity behaves differently.

You cannot directly set dependencies on filters, because they are of type IActionFilter and IExceptionFilter respectively. It made me believe that they had just been read, but that is not so. It is just that Unity needs to know the explicit type for the injection.

So, in the overridden method provided by the article, Unity users need to request filters for the corresponding types, and then create them.

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

And then in the overridden method do something like this:

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

A bit messy, but it only needs to be done once and keeps everything untied, as Ben suggests.

Another way is that you cannot call _container.BuildUp (filter) inside the foreach loop, because in this context the filter is readonly.

+2
source share

You have two options.

The first option is to write a custom ActionInvoker, which is not as strong as it seems. Check out this blog post . It specifically addresses NInject, but Unity supports property nesting, so you can change the Unity example.

This is an option that connects your IoC container and is not recommended.

 public class MyFilter { IMyService MyService {get; set;} MyFilter() : MyFilter(MyUnityContainer.Resolve<IMyService>()) { } MyFilter(IMyService service) { MyService = service; } } 
+1
source share

I also ran into this problem and now I have a working solution. This is similar to the solution described above, but with some slight differences, as well as with the added complete Unity code.

First, I will use property injection for the reason described above, and, as above, I will use the BuildUp method for Unity to embed properties in already created filters.

To do this, I have all my controllers inherited from the new custom base class. In this base class, I override the CreateActionInvoker method to set my own custom ActionInvoker.

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

Then in my CustomActionInvoker, I override the GetFilters method.

 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 

Unlike the above, I did not find that executing the assembly inside the For Each loop caused any problems. I also overcame the original problem of only having the object referenced through the interface using one of the other overloads of the BuildUp method, which takes System.Type, as well as the existing object.

When doing all of the above, I can now embed dependencies directly in my filters.

Any comments and thoughts are greatly appreciated.

Greetings Mike

+1
source share

All Articles