views:

580

answers:

1

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();
    }
}
+3  A: 

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);
    }
}