Skip to content

Instantly share code, notes, and snippets.

@droyad
Last active December 17, 2015 14:49
Show Gist options
  • Select an option

  • Save droyad/5627410 to your computer and use it in GitHub Desktop.

Select an option

Save droyad/5627410 to your computer and use it in GitHub Desktop.
Registering a WebAPI filter with #autofac based on action method attributes
builder.RegisterAuthorizationFilterForAttribute<MustBeLoggedInFilter, MustBeLoggedInAttribute>(ThisAssembly);
public static class AutofacExtensions
{
public static IRegistrationBuilder<object, IConcreteActivatorData, SingleRegistrationStyle> RegisterAuthorizationFilterForAttribute<TService, TAttribute>(
this ContainerBuilder builder,
params Assembly[] controllerAssemblies
) where TAttribute : Attribute
where TService : class
{
IRegistrationBuilder<object, IConcreteActivatorData, SingleRegistrationStyle> registration = builder.RegisterType<TService>();
var genericMethod = GetExtensionMethodToCall();
var actions = GetControllerActionsWithAttribute<TAttribute>(controllerAssemblies);
foreach (var action in actions)
{
// would be nice to create a Autofac.Integration.Mvc.FilterMetadata here instead
//Autofac.Integration.WebApi.RegistrationExtensions.AsWebApiAuthorizationFilterFor<EventController>(registration, c => c.Get(null));
var expression = CreateControllerActionExpression(action);
var method = MakeExtensionMethodForThisController(genericMethod, action);
method.Invoke(null, new object[] { registration, expression });
}
return registration.InstancePerApiRequest();
}
private static IEnumerable<MethodInfo> GetControllerActionsWithAttribute<TAttribute>(Assembly[] controllerAssemblies) where TAttribute : Attribute
{
var actions = from a in controllerAssemblies
from t in a.GetTypes()
where typeof (IHttpController).IsAssignableFrom(t)
from m in t.GetMethods()
where m.GetCustomAttribute<TAttribute>() != null
select m;
return actions;
}
private static MethodInfo MakeExtensionMethodForThisController(MethodInfo genericMethod, MethodInfo action)
{
var method = genericMethod.MakeGenericMethod(action.DeclaringType);
return method;
}
private static MethodInfo GetExtensionMethodToCall()
{
var genericMethod = typeof (Autofac.Integration.WebApi.RegistrationExtensions)
.GetMethods(BindingFlags.Static | BindingFlags.Public)
.Where(m => m.Name == "AsWebApiAuthorizationFilterFor")
.OrderByDescending(m => m.GetParameters().Length)
.First();
return genericMethod;
}
private static LambdaExpression CreateControllerActionExpression(MethodInfo action)
{
var controllerParameter = Expression.Parameter(action.DeclaringType);
var parameters = action.GetParameters().Select(p => Expression.Default(p.ParameterType));
var expression = Expression.Call(controllerParameter, action, parameters);
var actionType = typeof (Action<>).MakeGenericType(action.DeclaringType);
return Expression.Lambda(actionType, expression, controllerParameter);
}
}
@droyad
Copy link
Author

droyad commented May 22, 2013

Alternative is to register for all and check the attribute in the filter itself

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment