Last active
December 17, 2015 14:49
-
-
Save droyad/5627410 to your computer and use it in GitHub Desktop.
Registering a WebAPI filter with #autofac based on action method attributes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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); | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Alternative is to register for all and check the attribute in the filter itself