Out of Process Cassette.

Background
-----

Cassette is embarrassingly slow to load at app-start.  

It takes over 1 minute 20 seconds to do the following:

   *  Stop the w3wp process in task manager.
   *  hit the homepage (i.e. https://localhost)

Last summer we made this much much faster in the case where you are modifying files, but not recycling your app pools by keeping a static dictionary on the side.

Other Areas Investigated
---

In our brainstorming meeting we theorized that it was the mustache and less template generation that was the major bottleneck.  I attempted this and got it the point that the dependency graph was correctly generated, but the serving of the files wasnt quite right.  At this point I could evaulate the speed-up of lazy loading because serving the files is secondary.  I found that the app start time was decreased by around 1 minute.   While a nice gain, this isn't nearly fast enough to be acceptable. 

Change Summary
----

###  Initial Refactor

The current tip of master interacts directly with the dependency graph whenever it needs to.  To effectively swap between an in memory and out of process version of cassette this behavior needed to be refactored behind an interface:  ```IInteractWithDependencyGraph```.    This encapsulates the following functionality:

   *  Initial creation
   *  Reference a bundle per page load
   *  Rendering the script tags for the given set of referenced bundle
   *   Streaming Assets

The existing code was moved as-is into an implementation of this interface:  ```InMemoryDependencyGraphInteraction```.

Furthermore, to facilitate the switch between the two all requests for this interaction were changed to go through a factory:  ```IDependencyGraphInteractionFactory```.



###  Out of Process Cassette

The implementation of the out of process cassette adds three projects:

   *  A new project containing a hosted version of Cassette using a WCF service
   *  A simple console app to host the WCF service
   *  A simple test app that can be used to interact with the WCF service app
      
The first point is the bulk of the interesting changes:

   *  The cassette infrastructure requires the implementation of two abstract classes:
      *   ```CassetteServiceApplication``` implements ```CassetteApplicationBase```
      *  ```CassetteServiceContainerFactory``` implements ```CassetteApplicationContainerFactoryBase```
   *  Our initial refactor requires that we implement ```IInteractWithDependencyGraph``` for the service.
      *  The web application switches between ```WcfServiceDependencyGraphInteraction``` based on the web config
      *  The hosted application always uses the in memory option

   *  A ServiceContract used by the web application and hosted application to communicate by a ```NetNamedPipeBinding```.  This is ```ICassetteHost``` 
   *  ```CassetteHost```, which implements the service.


Evaluation of Changes
----

### Performance 

The following test was performed:

   *  Add new dlls to dependencies.
   *  Rebuild
   *  Kill w3wp process
   *  __Data Point 1__:   How long does it take to load the homepage (i.e. https://localhost)?
   *  Kill w3wp process
   *  __Data Point 2__:  How long does it take to load the homepage (i.e. https://localhost)?

For current master both data points are ~1 minute and 20 seconds.    For the out of process version of cassette the initial load is ~1 minute and 25 seconds, but the second load is __~24 seconds__.

### Stability

The changes have [successfully passed](https://ci.zocdoc.com:801/viewLog.html?buildId=446246&buildTypeId=bt256) on demand for lastCIPass and the updated dependency branch:

![image](https://f.cloud.github.com/assets/2537407/754227/f057e54a-e581-11e2-8d66-6f00fcaa5f8e.png)


Remaining Steps
---

   *  Review the code
   *  Pilot on the patient team
   *  ~~Run in on demand~~

Enabling Locally
---

By default cassette should behave exactly how it does now by using the InMemoryDependencyGraphInteraction.

To use the out of process version you need to run CassetteHostingApp.exe and put the following in your web.config:

```C#
<configSections>   
 <section name="cassette" type="Cassette.Configuration.CassetteConfigurationSection" />
</configSections>

<cassette 
     UseOutOfProcessCassette="true"  
     AppDomainAppPath="C:\src\zocdoc.web\zocdoc_web\ZocDoc.Web\"
     AppDomainAppVirtualPath="/"
     AssemblyPath="C:\src\zocdoc.web\zocdoc_web\ZocDoc.Web\Bin\ZocDoc.WebApp.dll" />
```