Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save alexhiggins732/8f8cc5a0dfca35e1dab938f1197d059c to your computer and use it in GitHub Desktop.
Save alexhiggins732/8f8cc5a0dfca35e1dab938f1197d059c to your computer and use it in GitHub Desktop.
Generic Nancy API Module
class Program
{
static void Main(string[] args)
{
HostConfiguration hostConfigs = new HostConfiguration()
{
UrlReservations = new UrlReservations() { CreateAutomatically = true }
};
using (var host = new NancyHost(hostConfigs, new Uri("http://localhost:8080")))
{
host.Start();
Console.WriteLine("Server started at http://localhost:8080");
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
}
}
public interface IGenericLogger
{
Guid NewGuid();
}
public class GenericService : IGenericLogger
{
public Guid NewGuid() => Guid.NewGuid();
}
public abstract class NancyApiModule<TService> : NancyModule//, IInterceptor<TService>
where TService : class
{
private TService implementation;
//private ConcurrentDictionary<Type, Action<Castle.DynamicProxy.IInvocation>> executeMethods;
public NancyApiModule(TService service)
{
this.implementation = service;
var serviceType = typeof(TService);
if (!serviceType.IsInterface)
throw new NotImplementedException();
var serviceRoot = serviceType.Name;
var methods = serviceType.GetMethods();
foreach (var method in methods)
{
bool returnsTask = method.ReturnType.BaseType == typeof(Task); ;
var endpoint = $"{serviceRoot}/{method.Name}";
Post(endpoint, async (ctx, token) =>
{
try
{
using (var reader = new StreamReader(Request.Body))
{
var incomingJson = await reader.ReadToEndAsync();
var inputParameters = JObject.Parse(incomingJson);
var paramDict = inputParameters.ToObject<Dictionary<string, string>>();
var keys = paramDict.Keys.ToList();
//var jsonParameters = inputParameters["Value"] as JArray;
var parameterTypes = method.GetParameters().Select(p => p.ParameterType).ToArray();
object[] parameters = new object[parameterTypes.Length];
for (var i = 0; i < parameters.Length; i++)
{
var type = parameterTypes[i];
// deserialize each parameter to it's respective type
var json = keys[i].ToString();
parameters[i] = JsonConvert.DeserializeObject(json, type);
}
object result = null;
if (returnsTask)
{
dynamic task = method.Invoke(implementation, parameters);
result = await task;
}
else
{
result = method.Invoke(implementation, parameters);
}
return JsonConvert.SerializeObject(result);
}
}
catch (Exception ex)
{
var errorData = new Dictionary<string, object>();
errorData["$exception"] = true;
errorData["$exceptionMessage"] = ex.InnerException.Message;
return JsonConvert.SerializeObject(errorData);
}
});
}
}
}
public class NancyGeneric : NancyApiModule<IGenericLogger>
{
public NancyGeneric(IGenericLogger service) : base(service)
{
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment