Filters Using IoC and Property Injection.txt.txt
//Filters Using IoC and Property Injection

//A resolver needs to be implemented to build up filters with the Web Api config when the filter has IoC dependent objects.

//Firstly add Unity Web API Bootstrapper to your project.

//Now create an ActionDescriptorFilterProvider class which implements the IFilterProvider interface. This will be used to resolve the ActionFilters.

using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Microsoft.Practices.Unity;
 
namespace WebApi2Attributes.App_Start
{
    public class WebApiUnityActionFilterProvider : ActionDescriptorFilterProvider, IFilterProvider
    {
        private readonly IUnityContainer container;
 
        public WebApiUnityActionFilterProvider(IUnityContainer container)
        {
            this.container = container;
        }
 
        public new IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor)
        {
            var filters = base.GetFilters(configuration, actionDescriptor);
            var filterInfoList = new List<FilterInfo>();
 
            foreach (var filter in filters)
            {
                container.BuildUp(filter.Instance.GetType(), filter.Instance);
            }
 
            return filters;
        }
 
        public  static void RegisterFilterProviders(HttpConfiguration config)
        {
            // Add Unity filters provider
            var providers = config.Services.GetFilterProviders().ToList();
            config.Services.Add(typeof(System.Web.Http.Filters.IFilterProvider), new WebApiUnityActionFilterProvider(UnityConfig.GetConfiguredContainer()));
            var defaultprovider = providers.First(p => p is ActionDescriptorFilterProvider);
            config.Services.Remove(typeof(System.Web.Http.Filters.IFilterProvider), defaultprovider);
        }
    }
}

//Register the new filter provider in the WebApiConfig in the App_Start
using System.Web.Http;
using Microsoft.Practices.Unity.WebApi;
using WebApi2Attributes.App_Start;
 
namespace WebApi2Attributes
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            config.DependencyResolver = new UnityDependencyResolver(UnityConfig.GetConfiguredContainer());
  
            // Web API routes
            config.MapHttpAttributeRoutes();
 
            WebApiUnityActionFilterProvider.RegisterFilterProviders(config);
 
        }
    }
}

//Now an attribute can be defined which uses Property Injection. Construction Injection cannot be used because the attribute requires a default constructor. The Dependency attribute from Unity requires that the property is not private.
using System.Diagnostics;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Microsoft.Practices.Unity;
 
namespace WebApi2Attributes.Attributes
{
    public class PropertyInjectionDebugActionWebApiFilter : ActionFilterAttribute
    {
        [Dependency]
        internal IDummyBusinessClass MyDummyBusinessClass { get; set; }
 
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            Debug.WriteLine("ACTION 1 DEBUG pre-processing logging and IoC:" + MyDummyBusinessClass.GetSomething());
        }
 
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            var objectContent = actionExecutedContext.Response.Content as ObjectContent;
            if (objectContent != null)
            {
                var type = objectContent.ObjectType; //type of the returned object
                var value = objectContent.Value; //holding the returned value
            }
 
            Debug.WriteLine("ACTION 1 DEBUG  OnActionExecuted Response " + actionExecutedContext.Response.StatusCode.ToString());
        }
    }
}

//The Unity objects need to be registered with Unity. This is done in the App_Start/UnityConfig class.
public static void RegisterTypes(IUnityContainer container)
{
  container.RegisterType<IDummyBusinessClass,  DummyBusinessClass>();
  container.RegisterType<PropertyInjectionDebugActionWebApiFilter>();       
}

//Now the property injection attribute can be used in the controller.
[PropertyInjectionDebugActionWebApiFilter]
[RouteAttribute("test6")]
[AcceptVerbs("GET")]
[ActionEditDataDebugActionWebApiFilter]
public IEnumerable<string> PropertyInjectionAttributeActionsDebugAttribute()
{
    return new string[] { "value1" };
}