Last active
August 29, 2015 14:16
-
-
Save milutinovici/9bc3c22fc962175c8084 to your computer and use it in GitHub Desktop.
asp.net 5 generic controllers
This file contains 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
public class GenericActionInvoker : ControllerActionInvoker | |
{ | |
protected override async Task<IActionResult> InvokeActionAsync(ActionExecutingContext actionExecutingContext) | |
{ | |
var actionMethodInfo = _descriptor.MethodInfo; | |
//find action | |
if(actionExecutingContext.Controller.GetType().IsGenericType) | |
{ | |
var parameters = actionMethodInfo.GetParameters().Select(x => x.ParameterType).ToArray(); | |
actionMethodInfo = actionExecutingContext.Controller.GetType().GetMethod(actionMethodInfo.Name, parameters); | |
} | |
var actionReturnValue = await ControllerActionExecutor.ExecuteAsync(actionMethodInfo, actionExecutingContext.Controller, actionExecutingContext.ActionArguments); | |
var actionResult = CreateActionResult( | |
actionMethodInfo.ReturnType, | |
actionReturnValue); | |
return actionResult; | |
} | |
} | |
This file contains 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
public class GenericActionInvokerProvider : IActionInvokerProvider | |
{ | |
public void OnProvidersExecuting(ActionInvokerProviderContext context) | |
{ | |
var actionDescriptor = context.ActionContext.ActionDescriptor as ControllerActionDescriptor; | |
if (actionDescriptor != null) | |
{ | |
// essentially just calling different constructor | |
context.Result = new GenericActionInvoker( | |
context.ActionContext, | |
_filterProviders, | |
_controllerFactory, | |
actionDescriptor, | |
_inputFormattersProvider, | |
_argumentBinder, | |
_modelBinderProvider, | |
_modelValidationProviderProvider, | |
_valueProviderFactoryProvider, | |
_actionBindingContextAccessor); | |
} | |
} | |
} |
This file contains 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
public class GenericControllerFactory : DefaultControllerFactory | |
{ | |
//part of route that will represent generic type parameter | |
private const string TypeKey = "type"; | |
private readonly IControllerActivator _controllerActivator; | |
public GenericControllerFactory(IControllerActivator controllerActivator) : base(controllerActivator) | |
{ | |
_controllerActivator = controllerActivator; | |
} | |
// should be override | |
public override object CreateController(ActionContext actionContext) | |
{ | |
var actionDescriptor = actionContext.ActionDescriptor as ControllerActionDescriptor; | |
if (actionDescriptor == null) | |
{ | |
throw new ArgumentException("ReflectedActionDescriptor", "actionContext"); | |
} | |
var controllerType = actionDescriptor.ControllerTypeInfo.AsType(); | |
//helper class where i registered allowed types for generic parameters | |
if (controllerType.IsGenericType) | |
{ | |
var genericType = EntityHelper.GetType(GetGenericType(actionContext.RouteData)); | |
controllerType = controllerType.MakeGenericType(genericType); | |
} | |
var controller = _controllerActivator.Create(actionContext, controllerType); | |
base.ActivateProperties(controller, actionContext); | |
return controller; | |
} | |
//get generic type from route | |
private string GetGenericType(RouteData routeData) | |
{ | |
if (routeData == null) | |
{ | |
return null; | |
} | |
// Look up type in route data | |
object typeName = null; | |
routeData.Values.TryGetValue(TypeKey, out typeName); | |
return (string)typeName; | |
} | |
} |
This file contains 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
public class GenericControllerModelBuilder : DefaultControllerModelBuilder | |
{ | |
protected override ControllerModel CreateControllerModel(TypeInfo typeInfo) | |
{ | |
var attributes = typeInfo.GetCustomAttributes(inherit: true).OfType<object>().ToArray(); | |
var controllerModel = new ControllerModel(typeInfo, attributes); | |
//remove "`1" from generic type names | |
var name = typeInfo.Name.EndsWith("`1") ? typeInfo.Name.Substring(0, typeInfo.Name.Length - "`1".Length) : typeInfo.Name; | |
controllerModel.ControllerName = name.EndsWith(nameof(Controller), StringComparison.OrdinalIgnoreCase) ? | |
name.Substring(0, name.Length - nameof(Controller).Length) : name; | |
.... | |
} | |
} |
This file contains 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
public class GenericControllerTypeProvider : DefaultControllerTypeProvider | |
{ | |
private const string ControllerTypeName = nameof(Controller); | |
private static readonly TypeInfo ControllerTypeInfo = typeof(Controller).GetTypeInfo(); | |
private static readonly TypeInfo ObjectTypeInfo = typeof(object).GetTypeInfo(); | |
//just removed isGeneric check | |
protected override bool IsController(TypeInfo typeInfo, ISet<Assembly> candidateAssemblies) | |
{ | |
if (!typeInfo.IsClass) | |
{ | |
return false; | |
} | |
if (typeInfo.IsAbstract) | |
{ | |
return false; | |
} | |
if (!typeInfo.IsPublic) | |
{ | |
return false; | |
} | |
if (!typeInfo.Name.EndsWith(ControllerTypeName, StringComparison.OrdinalIgnoreCase) && | |
!DerivesFromController(typeInfo, candidateAssemblies)) | |
{ | |
return false; | |
} | |
if (typeInfo.IsDefined(typeof(NonControllerAttribute))) | |
{ | |
return false; | |
} | |
return true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment