4

I am trying to get dependency injection working on my action filters with property injection. I can't figure out how to automatically set dependencies on the filters. Here is the code I have so far.

public class UnityActionInvoker : ControllerActionInvoker
{
    IUnityContainer container;

    public UnityActionInvoker(IUnityContainer container) {
        this.container = container;
    }

    protected override ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters) {
        foreach (var filter in filters) {
            // HELP: dependency injection on all marked filter properties
        }

        return base.InvokeActionMethodWithFilters(controllerContext, filters, actionDescriptor, parameters);
    }
}

public class UnityControllerFactory : DefaultControllerFactory
{
    IUnityContainer container;

    public UnityControllerFactory(IUnityContainer container) {
        this.container = container;
    }

    protected override IController GetControllerInstance(Type controllerType) {
        Controller controller = null;

        if (controllerType != null) {
            if (!typeof(IController).IsAssignableFrom(controllerType)) {
                throw new ArgumentException(string.Format("Type requested is not a controller: {0}", controllerType.Name), "controllerType");
            }

            controller = container.Resolve(controllerType) as Controller;
            controller.ActionInvoker = new UnityActionInvoker(container);
        }

        return controller;
    }
}

public class AccessFilterAttribute : FilterAttribute, IActionFilter
{
    [Dependency]
    public IUserRepository UserRepository { get; set; }

    public void OnActionExecuting(ActionExecutingContext filterContext) {
        throw new NotImplementedException();
    }

    public void OnActionExecuted(ActionExecutedContext filterContext) {
        throw new NotImplementedException();
    }
}

1 Answer 1

5

The answer is:

public class UnityActionInvoker : ControllerActionInvoker
{
    IUnityContainer container;

    public UnityActionInvoker(IUnityContainer container) {
        this.container = container;
    }

    protected override ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters) {
        foreach (var filter in filters) {
            container.BuildUp(filter.GetType(), filter);
        }

        return base.InvokeActionMethodWithFilters(controllerContext, filters, actionDescriptor, parameters);
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Nice solution. But I think a better way is injecting the filters in ControllerActionInvoker.GetFilters method.
No, even my previous solution isn't the best. The best way is removing original providers in FilterProviders.Providers, then add your own UnityFilterProviders where the filters are built up.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.