Created
May 28, 2019 05:57
-
-
Save alexhiggins732/8f8cc5a0dfca35e1dab938f1197d059c to your computer and use it in GitHub Desktop.
Generic Nancy API Module
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
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