SignalR/SignalR — pull request #275 by pszmyd (2012-03-27 23:12:46+00:00)
Title: Dynamic hubs initial implementation.

As discussed here: https://github.com/SignalR/SignalR/issues/268

There are lots of file changes, but the default behavior stays the same. The main change is the addition of **Descriptor** objects:

* `HubDescriptor`, which holds information about the hub (name and type)
* `ActionDescriptor`, which holds information about the action and a delegate for easy invoking
* `ParameterDescriptor`, holding info about a parameter (name and type)

and appropriate **descriptor provider** interfaces, along with their default implementations:

* `IHubDescriptorProvider`, with default `ReflectedHubDescriptorProvider` class
* `IActionDescriptorProvider`, with default `ReflectedActionDescriptorProvider` class

*These interfaces add important **extension points** - there can exist **multiple implementations** in addition to reflection-based default ones. It gives the possibility to eg. attach actions to hubs at runtime, dynamically create hubs etc. Generally speaking - **hub and action descriptors can come from different sources**.
The only thing you have to do is to register your custom provider with the dependency resolver.*

**The core class, `DefaultHubManager` (implementing `IHubManager`) resolves available providers and uses their merged outputs to provide it's services.**

All necessary classes (hub dispatcher, JS generator etc.) were refactored to make use of `IHubManager`.

*Unit tests (`DefaultActionResolverTest`) were also changed to utilize the new classes. All tests are being passed. The current implementation needs some more unit tests, which I'll provide in next few days. I've thoroughly tested changes using all of the included samples and everything works perfectly.*

----------
I've also added some fixes and performance tweaks:

1. **Peformance** - resolving an action takes ~20x less time in comparison to current version (resolving an action 100k times in a loop took **~120ms, in comparison to ~3000ms** as we have now). I've added a performance test to `DefaultActionResolverTest`. This is mainly because of dictionary-based caching.
2. **Fixes** - there are a few, eg. moving the ASP.NET-specific type resolver registration code from handler to the bootstrapper for performance.