Skip to content

Instantly share code, notes, and snippets.

@thecodejunkie
Last active December 10, 2015 11:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save thecodejunkie/4429702 to your computer and use it in GitHub Desktop.
Save thecodejunkie/4429702 to your computer and use it in GitHub Desktop.
Async requiring you return Task/Task<T>/void =( Trying to make Get[] work for both Async and non-async, but since using the async keyword requires you to return void/Task/Task<T> and since you cannot overload based on return type.. we're screwed. You cannot even return a type, which can be implicitly cast to Task/Task<T> because you'll get a com…
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;
public class Fixture
{
[Fact]
public void Should_FactMethodName()
{
var module = new Class1();
var result = module.routes["/"].Invoke(new object());
var i = 10;
}
}
public class Class1 : Module
{
public Class1()
{
Get["/"] = x =>
{
return "non async";
};
Get["/stuff"] = async x =>
{
var client = new HttpClient();
var result = await client.GetAsync("http://www.nancyfx.org");
var content = await result.Content.ReadAsStringAsync();
return content;
};
}
}
public class Module
{
public readonly IDictionary<string, Func<dynamic, dynamic>> routes = new Dictionary<string, Func<dynamic, dynamic>>();
public Builder Get
{
get { return new Builder(this); }
}
public class Builder
{
private readonly Module module;
public Builder(Module module)
{
this.module = module;
}
//public Func<dynamic, dynamic> this[string path]
//{
// set { this.module.routes.Add(path, value); }
//}
public Func<dynamic, Task<dynamic>> this[string path]
{
set { this.module.routes.Add(path, value); }
}
}
}
@yreynhout
Copy link

What's wrong with adding a GetAsync["/stuff"]?

@thecodejunkie
Copy link
Author

@yreynhout don't really like the segmentation of the API =/

@yreynhout
Copy link

While I agree with the sentiment, do consider that it is the norm to suffix "Async" and might even lower the bar for entry for new users of your framework.

@benaichouchem
Copy link

I believe the async is pattern based. The compiler expects the awaitable type to implement certain interface, or have certains methods. Task/Task happen to have those methods. http://msmvps.com/blogs/jon_skeet/archive/2011/05/13/eduasync-part-2-the-shape-of-the-caller-async-method-boundary.aspx .

I believe the methods have changed in the release version.

@prabirshrestha
Copy link

What about forcing return type as Task<dynamic>. This is a huge breaking change though. but might be worth it.

Get["/"] = _ => Task.FromResult("hi");

Task.FromResult is only present in .net 4.5+, so adding a helper method in NancyModule could be good.

Get["/"] = _ => ToTask("hi");

ToTask is a helper method.

private Task<T> ToTask<T>(T value) {
     var tcs = new TaskCompletionSource<T>();
     tcs.TrySetResult(value);
     return tcs.Task;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment