Skip to content

Instantly share code, notes, and snippets.

@shoop
Last active June 9, 2016 10:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shoop/6a8af9972e0ebaebd373138eb13cc6fc to your computer and use it in GitHub Desktop.
Save shoop/6a8af9972e0ebaebd373138eb13cc6fc to your computer and use it in GitHub Desktop.
public class HomeModule : NancyModule
{
[Route("/claims/{Type}")]
public class ClaimRequest
{
public string Type;
}
public class ClaimResponse
{
public string Type;
public string Value;
}
public object GetHandler(ClaimRequest request)
{
var claim = ClaimsPrincipal.Current.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/" + request.Type);
if (claim == null)
return HttpStatusCode.NotFound;
return new ClaimResponse
{
Type = request.Type,
Value = claim.Value,
};
}
}
public class NancyBootstrapper : DefaultNancyBootstrapper
{
protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
{
// Get all classes marked with a route attribute
var dtoClasses = new List<Type>();
dtoClasses.AddRange(Assembly.GetExecutingAssembly().GetTypes().Where(type => Attribute.IsDefined(type, typeof(RouteAttribute))));
var referencedAssemblyNames = Assembly.GetExecutingAssembly().GetReferencedAssemblies();
foreach (var assemblyName in referencedAssemblyNames)
{
var assembly = Assembly.Load(assemblyName);
dtoClasses.AddRange(assembly.GetTypes().Where(type => Attribute.IsDefined(type, typeof(RouteAttribute))));
}
// Loop over all modules and register routes for DTOs found
// XXX: returns 0 modules?!
//foreach (var module in GetAllModules(container))
//{
var module = GetModule(container, typeof(HomeModule));
foreach (var methodInfo in module.GetType().GetMethods())
{
var parameters = methodInfo.GetParameters();
foreach (var param in parameters)
{
var dtoClass = dtoClasses.SingleOrDefault(t => t == param.ParameterType);
if (dtoClass != null)
{
// Found a method with this DTO as parameter, add a route to it on the module
((NancyModule)module).AddRouteForDTO(dtoClass, methodInfo);
}
}
}
//}
}
}
public static class NancyModuleExtensions
{
// XXX: should be private, fix reflection first
public static object RunHandlerInternal<TIn>(this NancyModule module, MethodInfo handler)
{
TIn model;
try
{
model = module.BindAndValidate<TIn>();
if (!module.ModelValidationResult.IsValid)
{
return HttpStatusCode.InternalServerError;
}
}
catch (ModelBindingException)
{
return HttpStatusCode.InternalServerError;
}
return handler.Invoke(module, new object[] { model });
}
public static void AddRouteForDTO(this NancyModule module, Type dto, MethodInfo handlerInfo)
{
var routeInfo = dto.GetCustomAttribute<RouteAttribute>();
// Find the RunHandlerInternal<TIn> extension method to call
MethodInfo handlerFunction = null;
foreach (var mi in typeof(NancyModuleExtensions).GetMethods())
{
if (mi.IsGenericMethod && mi.Name == "RunHandlerInternal")
{
handlerFunction = mi;
break;
}
}
if (handlerFunction == null)
throw new ApplicationException("could not find handler function");
// Bind the type of DTO to the invocation of RunHandler<TIn>
var concreteHandleFunction = handlerFunction.MakeGenericMethod(dto);
// Invoke handlerInfo correctly
if (routeInfo.HttpVerbLimits.Contains("GET"))
module.Get[routeInfo.Route] = _ => concreteHandleFunction.Invoke(module, new object[] { module, handlerInfo });
// XXX: etc...
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment