ploeh / Hyprlinkr

A URI building helper library for ASP.NET Web API
MIT License
197 stars 34 forks source link

Feature/improve readability #13

Closed dhilgarth closed 12 years ago

dhilgarth commented 12 years ago

I changed Arg.OfType<T>() to Arg<T>.Any. The parenthesis at the end of OfType made the code actually pretty hard to read and author, because their already are quite a lot parenthesis at the end anyway.

Please compare:

if (_verifier.Verify<FooController>(actionContext, c => c.GetById(Arg.OfType<int>())))

if (_verifier.Verify<FooController>(actionContext, c => c.GetById(Arg<int>.Any)))

This is a breaking change.

BTW: I really would like to have a syntax like this:

if (_verifier.Verify<FooController>(actionContext, c => c.GetById))

Any ideas? I couldn't find a generic way without 10 overloads for the cases with zero to nine parameters.

ploeh commented 12 years ago

If you can make it work with method group style instead, that would certainly be preferable. I don't think you need to have 10 overloads for that. I like opinionated libraries, and in my opinion, if a method has more than 3-4 parameters it needs a redesign.

In AutoFixture, for example, I took a cue from .NET 3.5 where there were only so many variations of Func and Action...

In that spirit, 4-5 overloads should be enough. Perhaps they can even be created as extension method...?

dhilgarth commented 12 years ago

Honestly, I have no idea, how that would work in a way that would be better than what we currently have.

Supporting only the simple case of one input parameter and the return value would result in an extension method like this:

public static bool Verify<TController, TIn, TResult>(this ResourceLinkVerifier verifier, HttpActionContext actionContext, Func<TController, Func<TIn, TResult>> controllerAction)

Calling this would look like the following:

verifier.Verify<FooController, int, FooModel>(actionContext, c => c.GetById);

Thinking about overloads, I don't think that we will be able to create a syntax that doesn't require the types of the parameters and the return value in some way.

ploeh commented 12 years ago

You are probably right... In F# it might work, I think, but the C# type inference engine is weaker...

What if we defined a concrete class called Any with an implicit conversion to T?

Wouldn't that enable one to write new Any()?

dhilgarth commented 12 years ago

I don't think that that would work and it probably also wouldn't help:

  1. new Any() wouldn't work if there was an implicit conversion defined that converts to T. The syntax would need to be new Any<T>(), e.g. new Any<int>().
  2. This would make the code even harder to read than Arg.OfType<int>(), because there still would be the parenthesis at the end - which I found practically very confusing while writing real world code that uses this - and it would be less discoverable, which I agree might be subjective.
ploeh commented 12 years ago

Well, the github editor ate my angle brackets...

ploeh commented 12 years ago

This pull request can't be rebased due to the other pull request now being part of master. Please update the pull request.

dhilgarth commented 12 years ago

Can you please try again?