Adding dynamic redirects. Fix for #793

Fix for #793 

*Do not merge this yet!!!!*

This change removes all static binding redirects in app.config, and introduces dynamic redirects in core. The way this is done is by listening to the AssemblyResolve event on the AppDomain, and loading / returning the assembly to redirect to. It turns out using this technique you can swap on the fly and give a different assembly than what was requested.

At startup, it builds a map in map in memory based on the assemblies that scriptcs ships with ensuring that any requests for the same names will be redirected to it's version. It also ensures that any packages in the scriptcs packages folder take precedence over what the script pack / packages assemblies were actually compiled against.

Assembly black magic at its finest....

It appears to work so far :-)

This does not fix the Service Stack script pack issue, as there appears to be no magical fix for that other than updating the script pack. However, I was able to get the old Web Api script pack to work with the latest Web Api (see comments)


@glennblock 

> I started in Program, but I deliberately moved it to Core to make it more
transparent for hosters and not add more complexity. I don't think having
it in the builder is hurting anything.

Transparency is always my main aim, even though I miss may the target :wink:.

The semantics of `ScriptServicesBuilder` convey the building of an instance of `ScriptServices` very well but they don't hint at all at the wiring up of custom assembly resolution for the current `AppDomain`, and certainly not in the constructor. E.g. in a hosting scenario I create a `ScriptServicesBuilder` and suddenly custom assembly resolution is wired up in the currrent app domain as a side effect. What if I do this more than once? Indeed, we already have 3 points in our code base where we create an instance, https://github.com/scriptcs/scriptcs/blob/dev/src/ScriptCs/Program.cs#L16, https://github.com/scriptcs/scriptcs/blob/dev/src/ScriptCs/Command/CommandFactory.cs#L97 and https://github.com/scriptcs/scriptcs/blob/dev/src/ScriptCs/Command/CrossAppDomainExecuteScriptCommand.cs#L19. What happens if the custom resolver is are wired up multiple times?

We also have a case where we spin up a new app domain https://github.com/scriptcs/scriptcs/blob/dev/src/ScriptCs/Command/WatchScriptCommand.cs#L50 so that will also need the same custom resolution applied. This leads me to think we should make this into a service into which we can pass an app domain (including the current one).

I appreciate the desire to make things easy for hosting but in most hosting scenarios, will the custom resolution be necessary? I may be off track here but wouldn't the dependencies be likely to be known at design time in most hosting scenarios? In the spectrum of hosting, scriptcs is perhaps quite unique in that it's designed as an arbtrary host with the scripts and dependencies completely unknown at design time. In any case, whether the default is to have the custom resolution wired up or not, it think it needs to be easy to switch away from the default. I.e. if not enabled by default, it should be simple to enable and if enabled by default, it should be easy to disable. A host may also want to wire up it's own custom assembly resolution and not have anything else interfering with it which is another reason it should be easy to disable if enabled by default. I guess if it were put into a service then it could be overrideable just like all the others.

Anyway, enough brain dumping :smile:. Keen to hear thoughts.