title: Test ControllerFactory (pre-start initialization stage)
body: <p>I want to write a unit test that verifies my route registration and ControllerFactory so that given a specific URL, a specific controller will be created.  Something like this:</p>
  
  <pre><code>Assert.UrlMapsToController("~/Home/Index",typeof(HomeController));
  </code></pre>
  
  <p>I've modified code taken from the book "Pro ASP.NET MVC 3 Framework", and it seems it would be perfect except that the ControllerFactory.CreateController() call throws an InvalidOperationException and says <code>This method cannot be called during the application's pre-start initialization stage.</code></p>
  
  <p>So then I downloaded the MVC source code and debugged into it, looking for the source of the problem.  It originates from the ControllerFactory looking for all referenced assemblies - so that it can locate potential controllers.  Somewhere in the CreateController call-stack, the specific trouble-maker call is this:</p>
  
  <pre><code>internal sealed class BuildManagerWrapper : IBuildManager {
      //...
  
      ICollection IBuildManager.GetReferencedAssemblies() {
          // This bails with InvalidOperationException with the message
          // "This method cannot be called during the application's pre-start 
          // initialization stage."
          return BuildManager.GetReferencedAssemblies();
      }
  
      //...
  }
  </code></pre>
  
  <p><a href="https://stackoverflow.com/a/3419815/284758">I found a SO commentary on this</a>.  I still wonder if there is something that can be manually initialized to make the above code happy.  Anyone?  </p>
  
  <p>But in the absence of that...I can't help notice that the invocation comes from an implementation of IBuildManager.  I explored <a href="http://blog.semanticsworks.com/2010/01/test-example-in-systemwebmvc.html" rel="nofollow noreferrer">the possibility of injecting my own IBuildManager</a>, but I ran into the following problems:</p>
  
  <ul>
  <li>IBuildManager is marked <code>internal</code>, so I need some other authorized derivation from it.  It turns out that the assembly <code>System.Web.Mvc.Test</code> has a class called <code>MockBuildManager</code>, designed for test scenarios, which is perfect!!!  This leads to the second problem.</li>
  <li>The MVC distributable, near as I can tell, does not come with the System.Web.Mvc.Test assembly (DOH!).</li>
  <li>Even if the MVC distributable did come with the System.Web.Mvc.Test assembly, having an instance of <code>MockBuildManager</code> is only half the solution.  It is also necessary to feed that instance into the <code>DefaultControllerFactory</code>.  Unfortunately the property setter to accomplish this is also marked <code>internal</code> (DOH!).</li>
  </ul>
  
  <p>In short, unless I find another way to "initialize" the MVC framework, my options now are to either:</p>
  
  <ul>
  <li>COMPLETELY duplicate the source code for DefaultControllerFactory and its dependencies, so that I can bypass the original <code>GetReferencedAssemblies()</code> issue.  (ugh!)</li>
  <li>COMPLETELY replace the MVC distributable with my own build of MVC, based on the MVC source code - with just a couple <code>internal</code> modifiers removed. (double ugh!)</li>
  </ul>
  
  <p>Incidentally, I know that the MvcContrib "TestHelper" has the appearance of accomplishing my goal, but I think it is merely using reflection to find the controller - rather than using the actual IControllerFactory to retrieve a controller type / instance.</p>
  
  <p>A big reason why I want this test capability is that I have made a custom controller factory, based on DefaultControllerFactory, whose behavior I want to verify.</p>